import sys
import PyQt6
from PyQt6.QtWidgets import QApplication, QMainWindow, QMessageBox
from PyQt6.QtCore import pyqtSlot,Qt
from PyQt6.QtSql import QSqlDatabase, QSqlQueryModel, QSqlQuery, QSqlTableModel
from PyQt6.QtGui import QStandardItemModel, QStandardItem, QColor
from PyQt6.QtCharts import QChart, QChartView, QBarSet, QBarSeries, QHorizontalBarSeries, QBarCategoryAxis,QValueAxis,QPieSeries
from Ui_mainwindow import Ui_MainWindow

class QmyMainWindow(QMainWindow):

    def __init__(self, parent=None):
        super().__init__(parent)
        #调用父类构造函数，创建窗体
        
        self.ui = Ui_MainWindow()
        #创建UI对象
        
        self.ui.setupUi(self)
        #构造UI界面
        
        self.setWindowTitle("三国志")
        self.dataModel = QStandardItemModel(self)  # 创建一个标准项模型
        self.ui.tableView.setModel(self.dataModel)  # 设置表格视图的模型
        self.ui.tableView.setAlternatingRowColors(True)  # 启用交替行颜色
        self.ui.treeWidget.setAlternatingRowColors(True)  # 启用交替行颜色
        
        self.__openDB()  # 打开数据库连接
        self.__generateData()  # 生成数据
        self.__surveyData()  # 分析数据
        self.__initBarChart()  # 初始化柱状图
        self.__initPieChart()  # 初始化饼图

    @pyqtSlot()
    def __openDB(self):
        """初始化数据库连接和模型"""
        # 创建一个新的数据库连接
        self.DB = QSqlDatabase.addDatabase('QODBC')
        
        # 配置连接参数
        connection_string = (
            "DRIVER={MySQL ODBC 9.3 Unicode Driver};"  # 确保这个驱动名称正确
            "SERVER=localhost;"
            "DATABASE=pyqt;"
            "USER=root;"
            "PASSWORD=123456;"  # 替换为你的MySQL密码
            "CHARSET=utf8mb4;"
        )
        
        self.DB.setDatabaseName(connection_string)
        
        if not self.DB.open():
            #打开数据库
            QMessageBox.warning(self, "错误", "打开数据库失败")
        
    @pyqtSlot()
    def __generateData(self): ##生成分数数据
        self.dataModel.clear()
        headerList=["姓名","统帅","武力","智力","政治","魅力","平均分"]
        self.dataModel.setHorizontalHeaderLabels(headerList) #设置表头文字

        qryStudList=QSqlQuery(self.DB) #学生信息列表
        qryStudList.exec("SELECT 姓名,统帅,武力,智力,政治,魅力 FROM sanguozhi")

        qryStudList.first()
        while (qryStudList.isValid()): #当前记录有效

            itemList=[]

            studName=qryStudList.value("姓名")
            item=QStandardItem(studName)#创建item
            itemList.append(item)#添加到列表

            avgScore=0

            studTongshuai=qryStudList.value("统帅")
            item=QStandardItem("%.0f"%studTongshuai)#创建item
            itemList.append(item)#添加到列表
            avgScore=avgScore+studTongshuai

            studWuli=qryStudList.value("武力")
            item=QStandardItem("%.0f"%studWuli)#创建item
            itemList.append(item)#添加到列表
            avgScore=avgScore+studWuli

            studZhili=qryStudList.value("智力")
            item=QStandardItem("%.0f"%studZhili)#创建item
            itemList.append(item)#添加到列表
            avgScore=avgScore+studZhili

            studZhengzhi=qryStudList.value("政治")
            item=QStandardItem("%.0f"%studZhengzhi)#创建item
            itemList.append(item)#添加到列表
            avgScore=avgScore+studZhengzhi

            studMeili=qryStudList.value("魅力")
            item=QStandardItem("%.0f"%studMeili)#创建item
            itemList.append(item)#添加到列表
            avgScore=avgScore+studMeili
            item=QStandardItem("%.1f"%(avgScore/5.0))#创建item
            itemList.append(item)#添加到列表

            self.dataModel.appendRow(itemList)#添加到模型

            if not qryStudList.next(): #指向下一条记录
                break

        
    @pyqtSlot()
    def __surveyData(self): ##统计各分数段人数

        for i in range(1, 6): ##姓名 1统帅 2武力 3智力 4政治 5魅力，range(1,6)即从1到5
            cnt50,cnt60,cnt70,cnt80,cnt90=0,0,0,0,0

            for j in range(self.dataModel.rowCount()):  #行数等于人数
                val=float(self.dataModel.item(j,i).text())  #分数

                if val<60:
                    cnt50 =cnt50+1
                elif (val>=60 and val<70):
                    cnt60 =cnt60+1
                elif (val>=70 and val<80):
                    cnt70 =cnt70+1
                elif (val>=80 and val<90):
                    cnt80 =cnt80+1
                else:
                    cnt90 =cnt90+1

            item = self.ui.treeWidget.topLevelItem(0)
            item.setText(i,str(cnt50))
            item = self.ui.treeWidget.topLevelItem(1)
            item.setText(i,str(cnt60))
            item = self.ui.treeWidget.topLevelItem(2)
            item.setText(i,str(cnt70))
            item = self.ui.treeWidget.topLevelItem(3)
            item.setText(i,str(cnt80))
            item = self.ui.treeWidget.topLevelItem(4)
            item.setText(i,str(cnt90))
        self.ui.treeWidget.resizeColumnToContents(0) #列宽自适应
        
    def __initBarChart(self):
        self.barChart = QChart()
        self.barChart.setTitle("Barchart演示")
        self.ui.chartViewBar.setChart(self.barChart)

    def draw_barChart(self, isVertical=True):
        chart = self.ui.chartViewBar.chart()
        chart.removeAllSeries()
        for axis in chart.axes():
            chart.removeAxis(axis)
        setTongshuai = QBarSet("统帅")
        nameList = []
        rowCount = self.dataModel.rowCount()
        for i in range(rowCount):
            item = self.dataModel.item(i,0)
            nameList.append(item.text())
            item = self.dataModel.item(i,1)
            setTongshuai.append(float(item.text()))

        
        if isVertical:
            seriesBar = QBarSeries()
        else:
            seriesBar = QHorizontalBarSeries()
            
        seriesBar.append(setTongshuai)
        chart.addSeries(seriesBar)


        studAxis = QBarCategoryAxis()
        studAxis.append(nameList)
        studAxis.setRange(nameList[0],nameList[rowCount-1])

        valueAxis = QValueAxis()
        valueAxis.setRange(0,100)
        valueAxis.setTickCount(6)
        valueAxis.setTitleText("分数")

        if isVertical:
            chart.addAxis(studAxis,Qt.AlignmentFlag.AlignBottom)
            chart.addAxis(valueAxis,Qt.AlignmentFlag.AlignLeft)
        else:
            chart.addAxis(studAxis,Qt.AlignmentFlag.AlignLeft)
            chart.addAxis(valueAxis,Qt.AlignmentFlag.AlignBottom)
        seriesBar.attachAxis(studAxis)
        seriesBar.attachAxis(valueAxis)
        

    @pyqtSlot()
    def on_btnBuildBarChart_clicked(self):
        self.draw_barChart(True)
    
    @pyqtSlot()
    def on_btnBuildBarChartH_clicked(self):
        self.draw_barChart(False)
    
    @pyqtSlot(int)
    def on_comboAnimation_currentIndexChanged(self,index):
        chart = self.getCurrentChart()
        if chart:
            chart.setAnimationOptions(QChart.AnimationOption(index))
    
    def __initPieChart(self):
        pieChart = QChart()
        pieChart.setTitle("Piechart演示")
        self.ui.chartViewPie.setChart(pieChart)
    
    @pyqtSlot()
    def on_btnDrawPieChart_clicked(self):
        chart =self.ui.chartViewPie.chart()  
        chart.legend().setAlignment(PyQt6.QtCore.Qt.AlignmentFlag.AlignRight)
        chart.removeAllSeries()

        colNo=1+self.ui.comboCourse.currentIndex() 
        seriesPie =  QPieSeries()  
        seriesPie.setHoleSize(self.ui.spinHoleSize.value()) 
        seriesPie.setPieSize(self.ui.pieSize.value())
        sec_count=5  
        seriesPie.setLabelsVisible(True)  

        for i in range(sec_count):  
            item=self.ui.treeWidget.topLevelItem(i)
            sliceLabel=item.text(0)+"(%s人)"%item.text(colNo)
            sliceValue=int(item.text(colNo))
            seriesPie.append(sliceLabel,sliceValue)  

        seriesPie.setLabelsVisible(True) 
        chart.addSeries(seriesPie)
        chart.setTitle("Piechart---"+self.ui.comboCourse.currentText())

    def getCurrentChart(self):
        currentIndex = self.ui.tabWidget.currentIndex()
        
        if currentIndex == 0:  # 柱状图tab
            return self.ui.chartViewBar.chart()
        elif currentIndex == 1:  # 堆叠柱状图tab
            return self.ui.chartViewStackedBar.chart()
        elif currentIndex == 2:  # 百分比柱状图tab
            return self.ui.chartViewPercentBar.chart()
        elif currentIndex == 3:  # 饼图tab
            return self.ui.chartViewPie.chart()
        else:
            return None

    def on_comboTheme_currentIndexChanged(self,index):
        chart = self.getCurrentChart()
        if chart:
            chart.setTheme(QChart.ChartTheme(index))

if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = QmyMainWindow()
    form.show()
    sys.exit(app.exec())